#pragma once

#include "Containers/String.h"

//interface for type instance
class ITypeInstance
{
public:
    virtual ~ITypeInstance() = default;

    virtual uint32_t GetSize()=0; //get size of this type, in bytes,for pre-allocated memory
    virtual uint64_t GetInstanceHash(const void * Instance) const =0; //get hash of instance of this type
    
    //check if this type's instance is safe to be force converted to other type
    //@Other : other type，impossible to be same as this type
    virtual bool IsForceConvertableTo(CType * Other) { return false;} 
    
    virtual bool IsInstanceEqual(const void * Instance0,const void * Instance1) const = 0; //compare instance of this type
    virtual void InitInstance(void* Memory)=0; //create instance of this type    
    virtual void EraseInstance(void* Instance)=0; //destroy instance of this type,but not free memory
    virtual void CloneInstance(const void* Instance,void * TargetMemory)=0; //clone instance of this type

    //allocate memory Initialize Instance 
    virtual void* CreateInstance() 
    {
        void * Memory=malloc(GetSize());
        InitInstance(Memory);
        return Memory;
    }
    
    
    virtual void ResetAllocated(void* Memory) =0 ;

//for debug
    virtual CString ToDebugString(const void * Instance) const = 0; //convert instance of this type to debug string
    //named child is a child with a name, like a field of a struct
    virtual int64_t GetDebugNamedChildNum(const void * Instance) const { return 0; } //get number of named children value
    virtual CType* GetDebugNamedChildType(int64_t Index,const void * Instance) const { return nullptr; } //get type of named children value
    virtual CString GetDebugNamedChildName(int64_t Index,const void * Instance) const { return U""; } //get name of named children value
    virtual const void* GetDebugNamedChildValue(int64_t Index,const void * Instance) const { return nullptr; } //get value of named children value

    //indexed child is a child with a index, like a element of a vector
    virtual int64_t GetDebugIndexedChildNum(const void * Instance) const { return 0; } //get number of indexed children value
    virtual CType* GetDebugIndexedChildType(int64_t Index,const void * Instance) const { return nullptr; } //get type of indexed children value
    virtual const void* GetDebugIndexedChildValue(int64_t Index,const void * Instance) const { return nullptr; } //get value of indexed children value
};

